package cn.the.angry.tests;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JPanel;
import org.jbox2d.collision.AABB;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;
import cn.the.angry.model.Ground;
import cn.the.angry.model.Pig;
import cn.the.angry.util.AngryPigDebugDraw;

public class PigLaunchTest2 extends AbstractTest {
	
	private int frames = 0;
	private long totalTime = 0;  
    private long curTime = System.currentTimeMillis();  
    private long lastTime = curTime;
    private int fps; 
		
	private final AABB worldAABB;
	private final World mWorld;
	private final Pig pig1;
	private final Ground ground;
	private enum LauncherState{READY,BEFORE_LAUNCH,AFTER_LAUNCH,UNAVAILABLE};
	private LauncherState state=LauncherState.READY;
	private final Point ORIBALLPOSTION=new Point(200, HEIGHT-390);
	private final Point ROPEPOINT1=new Point(ORIBALLPOSTION.x+25,ORIBALLPOSTION.y+20);
	private final Point ROPEPOINT2=new Point(ORIBALLPOSTION.x-15,ORIBALLPOSTION.y+20);
	private final int GROUND_HEIGHT=HEIGHT-200;
	
	public PigLaunchTest2(){
		worldAABB = new AABB();
		worldAABB.lowerBound.set(-100, -100);
		worldAABB.upperBound.set(1500, 1000);
				
		mWorld = new World(worldAABB, new Vec2(0f, 10f), true);
		
		pig1 = new Pig();
		pig1.getSprite().setCenterX(ORIBALLPOSTION.x);
		pig1.getSprite().setCenterY(ORIBALLPOSTION.y);
		
		ground = new Ground(mWorld, 0, GROUND_HEIGHT, WIDTH, HEIGHT);
				
		add(panel);
	}
	
	private final JPanel panel = new JPanel(){
		//private BufferedImage bufferImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		private Graphics2D g2;// = bufferImage.createGraphics();
		
		
		@Override
		public void update(Graphics g){
			paint(g);
		}
		
		@Override
		public void paint(Graphics g){
			g2 = (Graphics2D)g;
			mWorld.step(1.0f/60f, 10);
			g2.drawImage(backgroundBufferImage, 0, 0, null);
					
			if(state==LauncherState.BEFORE_LAUNCH || state==LauncherState.READY)
			{
				g2.setStroke(new BasicStroke(3f));
				g2.setColor(Color.BLACK);
				g2.drawLine(ROPEPOINT1.x, ROPEPOINT1.y, pig1.getSprite().getCenterX(), pig1.getSprite().getCenterY());
			}
			
			pig1.draw(g2);		
			
			if(state==LauncherState.BEFORE_LAUNCH || state==LauncherState.READY)
			{
				g2.drawLine(ROPEPOINT2.x, ROPEPOINT2.y, pig1.getSprite().getCenterX(), pig1.getSprite().getCenterY());
			}
			
			g2.drawString(("FPS is "+fps).intern(), 15, 15);
			//caculate time
			lastTime = curTime;  
            curTime = System.currentTimeMillis();  
            totalTime += curTime - lastTime;  
            if (totalTime > 1000) {  
                totalTime -= 1000;  
                fps = frames;  
                frames = 0;  
            }  
            ++frames;

            g2.drawImage(foregroundBufferImage, 0, 0, null);
            
            g2.dispose();
		}
	};
	
	private final Runnable update = new Runnable(){
		@Override
		public void run(){
			while (true) {
				panel.repaint();
			}
		}
	};
	
	public void startTest(){
		new Thread(update).start();
	}
	
	public void mouseOnPigAndDown(final MouseEvent e)
	{
		if(state==LauncherState.READY && 
		   pig1.getSprite().isCoordinateOnSprite(e.getX(), e.getY()))
			state=LauncherState.BEFORE_LAUNCH;
	}
	
	public void mouseOnPigAndUp(final MouseEvent e)
	{
		if(state==LauncherState.BEFORE_LAUNCH)
		{
			state=LauncherState.AFTER_LAUNCH;
			pig1.createPig(mWorld, pig1.getSprite().getX(), pig1.getSprite().getY(), 2f, 0.8f, 0.2f, 42f);
			pig1.getBody().setLinearVelocity(new Vec2(ORIBALLPOSTION.x-pig1.getSprite().getCenterX(), ORIBALLPOSTION.y-pig1.getSprite().getCenterY()));
		}
	}
	
	public void mouseOnPidAndDrag(final MouseEvent e)
	{
		if(state==LauncherState.BEFORE_LAUNCH)
		{
			final int RADIUS=100;
			int x=e.getX()-pig1.getSprite().getWidth()/2;
			int y=e.getY()-pig1.getSprite().getHeight()/2;
			final int z=(int) Math.sqrt(Math.pow(e.getX()-ORIBALLPOSTION.x,2)+Math.pow(e.getY()-ORIBALLPOSTION.y,2));
			if(z>RADIUS)
			{
				x=RADIUS*(x-ORIBALLPOSTION.x)/z+ORIBALLPOSTION.x;
				y=RADIUS*(y-ORIBALLPOSTION.y)/z+ORIBALLPOSTION.y;
			}
			pig1.getSprite().setX(x);
			pig1.getSprite().setY(y);
		}
	}
	
	public static void bindMouseEvents(final PigLaunchTest2 test)
	{
		test.addMouseListener(new MouseAdapter()
		{        	
        	@Override
        	public void mousePressed(final MouseEvent e)
        	{
        		test.mouseOnPigAndDown(e);
        	}
        	
        	@Override
        	public void mouseReleased(final MouseEvent e)
        	{
        		test.mouseOnPigAndUp(e);
        	}
		});
        
		test.addMouseMotionListener(new MouseMotionAdapter()
		{
			@Override
			public void mouseDragged(final MouseEvent e)
			{
				test.mouseOnPidAndDrag(e);
			}
		});
	}
	
	public static void main(String[] args)
    {
        final PigLaunchTest2 main = new PigLaunchTest2();
        main.setVisible(true);
        bindMouseEvents(main);
        
        new Thread(){
        	@Override
        	public void run(){
        		try {
        			Thread.sleep(1000);
				} catch (Exception e) {
				}
				main.startTest();
        	}
        }.start();
    }
}
